package com.example.financechain.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.financechain.Utils.GatewayUtilss;
import com.example.financechain.Utils.JsonData;
import com.example.financechain.Utils.UUIDUtils;
import com.example.financechain.config.CacheKeyManager;
import com.example.financechain.domain.DTO.RoleDTO;
import com.example.financechain.domain.entity.*;
import com.example.financechain.mapper.RoleMapper;
import com.example.financechain.service.IMenuService;
import com.example.financechain.service.IRoleCertificateService;
import com.example.financechain.service.IRoleMenuService;
import com.example.financechain.service.IRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.hyperledger.fabric.gateway.Contract;
import org.hyperledger.fabric.gateway.Gateway;
import org.hyperledger.fabric.gateway.Network;
import org.hyperledger.fabric.gateway.Transaction;
import org.hyperledger.fabric.sdk.Peer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author yy
 * @since 2023-04-13
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    private IMenuService iMenuService;

    @Autowired
    private IRoleMenuService iRoleMenuService;

    @Autowired
    private IRoleCertificateService roleCertificateService;

    @Autowired
    GatewayUtilss gatewayUtilss;

    @Override
    public JsonData addRole(RoleDTO roleDTO) throws NoSuchAlgorithmException {



        Role role = createRole(roleDTO);

        //根据账户类型来判断创建账号
        LambdaQueryWrapper<RoleCertificate> lambdaQueryWrapper =new LambdaQueryWrapper<>();
        List<RoleCertificate> certificates = roleCertificateService.list(lambdaQueryWrapper.eq(RoleCertificate::getRoleType, roleDTO.getType()).eq(RoleCertificate::getStatus,0));

        if (certificates.size()==0){
            return JsonData.buildError("不能认证,账户已近分配完");
        }

        //直接用第一个
        RoleCertificate roleCertificate = certificates.get(0);
        role.setRoleCertification(roleCertificate.getRoleCertification());

        createchainRole(role);

        save(role);
        UpdateWrapper<RoleCertificate> updateWrapper =new UpdateWrapper<>();
        roleCertificateService.update(updateWrapper.lambda().eq(RoleCertificate::getRoleCertification,roleCertificate.getRoleCertification()).set(RoleCertificate::getStatus,1));

        List<RoleMenu> roleMenus =new ArrayList<>();

        if (roleDTO.getType()==1){

            RoleMenu roleMenu = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_browser);
            RoleMenu roleMenu1 = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_browser_browsers);
            RoleMenu roleMenu2 = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_Todo);
            RoleMenu roleMenu3 = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_Todo_BankTodo);
            RoleMenu roleMenu4 = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_product);
            RoleMenu roleMenu5 = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_products_purchase);

            roleMenus.add(roleMenu);
            roleMenus.add(roleMenu1);
            roleMenus.add(roleMenu2);
            roleMenus.add(roleMenu3);
            roleMenus.add(roleMenu4);
            roleMenus.add(roleMenu5);



        }else {


            RoleMenu roleMenu = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_browser);
            RoleMenu roleMenu1 = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_browser_browsers);
            RoleMenu roleMenu2 = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_Todo);
            RoleMenu roleMenu3 = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_Todo_Todos);
            RoleMenu roleMenu4 = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_product);
            RoleMenu roleMenu5 = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_products_purchase);
            RoleMenu roleMenu6 = createRoleMenu(role.getRoleId(), CacheKeyManager.Admin_products_financing);

            roleMenus.add(roleMenu);
            roleMenus.add(roleMenu1);
            roleMenus.add(roleMenu2);
            roleMenus.add(roleMenu3);
            roleMenus.add(roleMenu4);
            roleMenus.add(roleMenu5);
            roleMenus.add(roleMenu6);
        }

        iRoleMenuService.saveBatch(roleMenus);

        return JsonData.buildSuccess(null,"认证成功");
    }

    public RoleMenu createRoleMenu(Long roleId,Long menuId){
        RoleMenu roleMenu = new RoleMenu();
        roleMenu.setRoleId(roleId);
        roleMenu.setMenuId(menuId);
        return roleMenu;
    }


    public Role createRole(RoleDTO roleDTO) throws NoSuchAlgorithmException {
        Role role =new Role();
        //设置用户名，登录用的
        role.setNickName(roleDTO.getNickName());
        //设置企业名称
        role.setRoleName(roleDTO.getRoleName());
        //设置法人名称
        role.setLegalname(roleDTO.getLegalname());
        //账户创建时间
        role.setRoleCreatedate(LocalDateTime.now());
        //密码加密
        String s = addMD5(roleDTO.getPassword());
        role.setPassword(s);

        role.setEmail(roleDTO.getEmail());
        role.setPhonenumber(roleDTO.getPhonenumber());

        //创建链账户
        role.setChainAccount(UUIDUtils.getUUID(10));
        //设置头像
        role.setAvatar("https://blog-xiaosheng.oss-cn-shanghai.aliyuncs.com/articleimg/20230416/e74320d427794957ace43c649ad02ef0heder.jpg");

        if (roleDTO.getType()==1){
            role.setRoleAccount(CacheKeyManager.FINANC_AMOUNT);
            role.setRoleType(1);
        }else {
            role.setRoleAccount(0L);
            role.setRoleType(2);
        }

        role.setStatus("1");

        return role;
    }

    private String  addMD5(String password) throws NoSuchAlgorithmException {

        MessageDigest md = MessageDigest.getInstance("MD5");

        // Add original string bytes to digest
        md.update(password.getBytes());

        // Get the hash's bytes
        byte[] bytes = md.digest();

        // Convert the bytes to a hexadecimal format
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }

        return sb.toString();

    }


    @Async("taskExecutor")
    public void createchainRole(Role role){

        Role from =new Role();
        from.setRoleCertification("Org5MSP");
        from.setRoleName("武汉学院");

        try (Gateway gateway = gatewayUtilss.build(from).connect()) {
            // Get the network and chaincode
            Network network = gateway.getNetwork("energycarchannel");
            Contract contract = network.getContract("transferfinance");

            // Set endorsement policy
            EnumSet<Peer.PeerRole> roles = EnumSet.of(Peer.PeerRole.ENDORSING_PEER);
            // ...

            // Submit transaction
            Transaction transaction = contract.createTransaction("CreateCompany")
                    .setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)));
            transaction.submit(role.getRoleName(), role.getRoleAccount().toString(), role.getRoleCertification());

            // Wait for transaction to complete and print transaction ID
            String txid = transaction.getTransactionId();
            System.out.println("txId:" + txid);


        } catch (Exception e) {
            // Handle exceptions
            e.printStackTrace();

        }
    }
}
